<?php

namespace App\Trip\Orders\BookOrders\Params;

use App\Models\Plane\PlaneOrders\PlaneOrder;
use App\Models\Task\SnapTasks\Repositories\Interfaces\SnapTaskRepositoryInterface;
use App\Trip\Enums\Plane\PlaneProviders;
use App\Trip\Orders\BookOrders\BookTypes;
use App\Trip\Orders\BookOrders\Params\AbstractOrderParam\AbstractMultiTripOrders;
use App\Trip\Orders\BookOrders\Params\AbstractOrderParam\AbstractOrderParam;
use App\Trip\Orders\BookOrders\Params\AbstractOrderParam\AbstractSnapOrderParam;
use App\Trip\Orders\BookOrders\Params\AbstractOrderParam\AbstractSnapOrdersParam;
use App\Trip\Orders\BookOrders\Params\AbstractParam\AbstractParam;
use App\Trip\Orders\BookOrders\Params\Plane\BookPlaneOrderParam;
use App\Trip\Orders\BookOrders\Params\Plane\ChangePlaneOrderParam;
use App\Trip\Orders\BookOrders\Plane\BuildChangeOrderData;
use App\Trip\Orders\BookOrders\Plane\BuildOrderData;
use Exception;
use Illuminate\Support\Facades\Validator;

class Param extends AbstractParam
{
    protected array   $params;
    private BookTypes $bookType;

    public function __construct(array $params, BookTypes $bookType)
    {
        $this->params = $params;

        if (!isset($this->params['user_id'])) {
            $this->params['user_id'] = $this->getUserId();
        }
        $this->bookType = $bookType;

    }

    public function getUserId(): string
    {
        return ($this->params['user_id'] ?? auth()->id()) ?: '';
    }

    public function getBookType(): BookTypes
    {
        return $this->bookType;
    }

    /**
     * 手机号 存在则验证
     * @throws Exception
     */
    public function getMobile(): string
    {
        // 需要验证手机号的有效性
        $mobile = $this->params['mobile'] ?? '';
        if ($mobile) {
            $validator = Validator::make($this->params,
                [
                    'mobile' => "phone",
                ],
                [
                    "mobile.phone" => "手机号格式错误",
                ]);

            if ($validator->fails()) {
                throw new Exception($validator->errors()->first());
            }
        }
        return $mobile;
    }

    // 修改任务原任务id

    /**
     * 下单,改签,抢票乘客参数 或 修改抢票原乘客信息
     * @throws Exception
     */
    public function getPassengersParam(): PassengersParam
    {
        if ($this->bookType->isSnapUpEdit()) {
            // 抢票任务的乘客信息
            $passengers = $this->getEditSnapOrderParam()
                               ->getSnapParam()
                               ->getTaskInfo()
                               ->getPassengers()
                               ->toArray();
        } else {
            // 下单,改签,抢票传入的乘客参数
            $passengers = $this->params['passengers'];
        }
        $passengerParam = new PassengersParam($passengers, $this->bookType);
        $passengerParam->setUserId($this->getUserId());
        return $passengerParam;
    }

    // 改签原单号

    /**
     * 编辑抢票单个订单
     *
     * @return AbstractSnapOrderParam
     * @throws Exception
     */
    public function getEditSnapOrderParam(): AbstractSnapOrderParam
    {
        $task_id = $this->getTaskId();
        /**
         * @var SnapTaskRepositoryInterface $taskRepo
         */
        $taskRepo = app(SnapTaskRepositoryInterface::class);
        if (!$task_id) {
            throw new Exception('参数错误');
        }
        $task_info = $taskRepo->findOneByTaskId($task_id);
        if ($task_info?->getUserId() != $this->getUserId()) {
            throw new Exception(404, "抢票任务不存在");
        }
        return new EditSnapOrderParam($this->params['order'], new SnapParam([
            'snap_level' => $this->params['snap_level'] ?? '',
            'task_info'  => $task_info,
        ]));
    }

    // 订票参数

    public function getTaskId(): string
    {
        return $this->params['task_id'] ?? '';
    }

    public function getOriginOrderSn(): string
    {
        return $this->params['order_sn'] ?? '';
    }

    public function getBookOrdersParam(): AbstractMultiTripOrders
    {
        return new BookOrdersParam($this->params['orders']);
    }

    /**
     * 目前接口仅支持单程
     * @return AbstractOrderParam
     * @throws Exception
     */
    public function getBookPlaneOrderParam(): AbstractOrderParam
    {
        $orderData                                = new BuildOrderData(PlaneProviders::from($this->params['provider']), $this->params['bookingTagKey']);
        $this->params['order']                    = $orderData->getOrderData();
        $this->params['order']['bookingTagKey']   = $this->params['bookingTagKey'];
        $this->params['order']['bookingTagValue'] = $orderData;
        $this->params['order']['provider']        = $this->params['provider'];
        return new BookPlaneOrderParam($this->params['order']);
    }

    /**
     * 改签参数
     * @throws Exception
     */
    public function getChangePlaneOrderParam(PlaneOrder $origin_order_info): AbstractOrderParam
    {
        $change_key                               = $this->params['order']['change_key'];
        $orderData                                = new BuildChangeOrderData(PlaneProviders::from($origin_order_info->order_service), $change_key);
        $this->params['order']                    = $orderData->getOrderData();
        $this->params['order']['bookingTagKey']   = $change_key;
        $this->params['order']['bookingTagValue'] = $orderData;
        return new ChangePlaneOrderParam($this->params['order'], $origin_order_info);
    }

    /**
     * 抢票多个订单
     *
     * @return AbstractSnapOrdersParam
     * @deprecated 目前不支持也未考虑如中转的抢票
     */
    public function getSnapOrdersParam(): AbstractSnapOrdersParam
    {
        return new SnapOrdersParam($this->params['orders'], new SnapParam([
            'stop_time'  => $this->params['stop_time'],
            'snap_level' => $this->params['snap_level'],
            'task_id'    => $this->params['task_id'] ?? '',
        ]));
    }

    // 改签订单参数

    /**
     * 抢票单个订单参数
     *
     * @return AbstractSnapOrderParam
     */
    public function getSnapOrderParam(): AbstractSnapOrderParam
    {
        return new SnapOrderParam($this->params['order'], new SnapParam([
            'stop_time'  => $this->params['stop_time'] ?? '',
            'snap_level' => $this->params['snap_level'] ?? '',
        ]));
    }

    // 当前用户id

    public function getChangeOrderParam($origin_order_info): AbstractOrderParam
    {
        return new ChangeOrderParam($this->params['order'], $origin_order_info);
    }
}